#include <Ogre.h>

#include "NetworkState.h"
#include "PlayState.h"
#include "IntroState.h"

using namespace Ogre;

NetworkState NetworkState::mNetworkState;

NetworkState::NetworkState() :
	mChatBox(0),
	spriteManager(0)
{
	mWindow = 0;
	mDebugOverlay = 0;
	displayCameraDetails = false;
	statsOn = false;
	mTimeUntilNextToggle = 0.0f;
}

void NetworkState::enter()
{
	mRoot = Root::getSingletonPtr();
	mWindow = mRoot->getAutoCreatedWindow();
	mDeviceManager = DeviceManager::getSingletonPtr();
	mGUIManager = GUIManager::getSingletonPtr();
	mKeyboard = mDeviceManager->mKeyboard;
	mMouse = mDeviceManager->mMouse;
	mDeviceManager->setBuffered(true);
	mChatBox = ChatBox::getSingletonPtr();
	mChatBox->setFadeOn(false);

	// Set up Debug Overlay
	mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");

	// Create SceneManager	
	mSceneMgr = mRoot->getSceneManager("plitzScene");

	// Create Camera
	mCamera = mSceneMgr->createCamera("NetCamera");

	// Create Viewport
	mViewport = mRoot->getAutoCreatedWindow()->addViewport(mCamera);
	mViewport->setBackgroundColour(ColourValue(0.0, 0.0, 0.0));

	// Create Sprite Manager
	spriteManager=new Ogre2dManager;
	spriteManager->init(mSceneMgr, Ogre::RENDER_QUEUE_OVERLAY, true);

	// Reigster GUI Items
	mGUIManager->registerScene(mSceneMgr);
	mGUIManager->setGUISheet(CEGUI::WindowManager::getSingletonPtr()->getWindow("Net/Sheet"));
	
	setupEventHandlers();

	// Set default values for each entry
	mGoBack = false;
	mStart = false;
	
}

void NetworkState::exit()
{
	// Removing Game GUI
	mChatBox->clear();
	spriteManager->end();
	delete spriteManager;

	// Switch off debug overlays
	displayCameraDetails = false;
	statsOn = false;
	mDebugOverlay->hide();

	mSceneMgr->clearScene();
	mSceneMgr->destroyAllCameras();
	mRoot->getAutoCreatedWindow()->removeAllViewports();
}

void NetworkState::pause()
{
}

void NetworkState::resume()
{
}

bool NetworkState::keyPressed(const OIS::KeyEvent &arg)
{
	if (arg.key == OIS::KC_S)	// S to Start
		mStart = true;
	if (arg.key == OIS::KC_B || arg.key == OIS::KC_ESCAPE)	// B to Back
		mGoBack = true;

	// Toggle Debug Overlay
	if (arg.key == OIS::KC_F1 && mTimeUntilNextToggle <= 0 && Config::getInstance()->cfg_debugOn)
	{
		statsOn = !statsOn;
		mTimeUntilNextToggle = 0.5;
		if (statsOn) mDebugOverlay->show();
		else mDebugOverlay->hide();
	}

	// ChatBox keys
	if (arg.key == OIS::KC_Y && mTimeUntilNextToggle <= 0)
	{
		mChatBox->addText("You pressed the 'Y' Key in Net State.");
		mTimeUntilNextToggle = 0.3;
	}
	if (arg.key == OIS::KC_U && mTimeUntilNextToggle <= 0)
	{
		mChatBox->addText("You pressed the 'U' Key in Net State.");
		mTimeUntilNextToggle = 0.3;
	}

	return true;
}

bool NetworkState::keyReleased(const OIS::KeyEvent &arg)
{
	return true;
}

bool NetworkState::mouseMoved( const OIS::MouseEvent &arg )
{
	CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
	return true;
}

bool NetworkState::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
	return true;
}

bool NetworkState::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
	CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
	return true;
}

bool NetworkState::frameStarted(const FrameEvent& evt)
{
	// Update toggle buffering time
	if (mTimeUntilNextToggle >= 0)
				mTimeUntilNextToggle -= evt.timeSinceLastFrame;

	// Updating debug overlay stats
	updateStats();

	// Update chatbox
	mChatBox->loop(evt.timeSinceLastFrame);

	drawSprites();

	if (mKeyboard) 
		mKeyboard->capture();
	if (mMouse)
		mMouse->capture();
	return true;
}

bool NetworkState::frameEnded(const FrameEvent& evt)
{
	if (mGoBack)
		changeState(IntroState::getInstance());
	if (mStart)
		changeState(PlayState::getInstance());
	return true;
}

void NetworkState::createScene()
{
}

void NetworkState::setupEventHandlers()
{
	CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();
	CEGUI::Window *start = wmgr->getWindow((CEGUI::utf8*)"Net/StartButton");
	start->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetworkState::handleStart, this));
    CEGUI::Window *back = wmgr->getWindow((CEGUI::utf8*)"Net/BackButton");
	back->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&NetworkState::handleBack, this));
}

bool NetworkState::handleBack(const CEGUI::EventArgs& e)
{
	mGoBack = true;
	return true;
}

bool NetworkState::handleStart(const CEGUI::EventArgs& e)
{
	mStart = true;
	return true;
}

void NetworkState::drawSprites()
{
}